【Sassで解決】CSSの@importはどれだけ悪影響なのか自分で試してみる
はじめに
Webサイトの高速化について調べてみるとCSSの@import url();は使わない方が良いという指摘をよく見かけます。
問題となるのはパラレルロード(複数のリソースを同時にロードする)ができなくなる場合があることと、CSSの読み込み順序が変わってしまうことがあるようです。
実際にどれだけ読み込み速度に問題があるのか、3つの読み込み方で試してみたいと思います。
比較する3つの読み込み方
今回はこの3つで読み込みを比較してみます。
- CSSの@import url();で読み込む
- HTMLのlink要素で別々に読み込む
- Sassで@importして1つにまとめてlink要素で読み込む
対象ブラウザ
今回の検証ブラウザはChromeとInternet Explorerです。
どちらも備え付けの開発者ツールで検証します。
今回計測したサンプル
サンプルはこちらに公開しているので問題があれば指摘してください。
- ソースコード:github:css_import_sample
1,準備
HTMLのbody部分は共通になります。
<body> <header> <h1>Site ID</h1> <nav> <ul> <li><a href="#">nav 01</a></li> <li><a href="#">nav 02</a></li> <li><a href="#">nav 03</a></li> </ul> </nav> </header> <section id="container"> <header> <h1>Main title</h1> <p>Sub title</p> </header> <main class="editable"> <h2 id="toc-title">title</h2> <p>this is dammy text.</p> </main> </section> <footer> <p>Copyright</p> </footer> </body>
1.1,CSSの@import url();で読み込む
以下のようなファイル構造にします。
- css/
- module/
- header.css
- container.css
- footer.css
- editable.css
- button.css
- common.css
- style.css(import)
- module/
- css_import.html
ポイントとなる読み込み部分:style.css
/* ***************************** * * Import CSS file. * **************************** */ @import url('common.css'); @import url('module/header.css'); @import url('module/container.css'); @import url('module/footer.css'); @import url('module/editable.css'); @import url('module/button.css');
1.2,HTMLのlink要素で別々に読み込む
こちらは上記の構造とほぼ同じですが、import用のstyle.cssを省きます。
- css/
- module/
- header.css
- container.css
- footer.css
- editable.css
- button.css
- common.css
- module/
- css_import.html
ポイントとなる読み込み部分:css_link.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>CSS Link Tag Sample</title> <link rel='stylesheet' href='css/common.css' type='text/css' media='all' /> <link rel='stylesheet' href='css/module/header.css' type='text/css' media='all' /> <link rel='stylesheet' href='css/module/container.css' type='text/css' media='all' /> <link rel='stylesheet' href='css/module/footer.css' type='text/css' media='all' /> <link rel='stylesheet' href='css/module/editable.css' type='text/css' media='all' /> <link rel='stylesheet' href='css/module/button.css' type='text/css' media='all' /> </head>
1.3,Sassで@importして1つにまとめてlink要素で読み込む
Sassを使いコンパイル後のまとめられたCSSのみをlink要素でHTMLに読み込みます。
モジュール化されたSCSSファイルはパーシャルという「_」を付けた読み込み専用ファイルにしてstyle.scssに読み込ませます。
- scss/
- module/
- _header.scss
- _container.scss
- _footer.scss
- _editable.scss
- _button.scss
- _common.scss
- style.scss
- module/
- output/
- style.css
- css_import.html
ポイントとなる読み込み部分:style.scss
/* ***************************** * * Import file to Scss or Sass. * **************************** */ @import "common"; @import "module/header"; @import "module/container"; @import "module/footer"; @import "module/editable"; @import "module/button";
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>SCSS @import Sample</title> <link rel='stylesheet' href='output/style.css' type='text/css' media='all' /> </head>
2,読み込んだ結果を比較検証
結果は以下の比較表を見て貰えるとわかりますが、link要素で連続的に読み込むよりも@importが遅いことがわかります。
また、Sassでコンパイルしたものがリクエストも少なくロードしたサイズまで1/3程度になっています。
比較表
対象ブラウザ | 読み込み方法 | リクエスト数 | サイズ | 読み込み時間 |
---|---|---|---|---|
Chrome | CSS @import | 8 | 1.75KB | 607ms |
link | 7 | 1.53KB | 437ms | |
Sass compile | 2 | 448B | 388ms | |
Internet Explorer | CSS @import | 8 | 1.23KB | 924ms |
link | 7 | 1.07KB | 390ms | |
Sass compile | 2 | 315B | 374ms |
Chromeで検証したタイムライン
CSS @import
インポート用のstyle.cssを読み込んでから@import対象のファイルのリクエストを出しているのでその分読み込み完了時間が遅くなっています。
また、若干ですが@importしているファイルの読み込み時間に差があり、パラレルロードが行えていないように見受けられます。@import対象のファイルサイズが重くなるとロードの順序が顕著に表れてくるかもしれません。
CSS link要素
スムーズに読み込まれていますが、リクエスト数が多いため待機時間とリクエストヘッダの分ファイルサイズが大きくなっています。
Sass compile
リクエスト数も少なくファイルサイズも小さいためとても理想的です。
Internet Explorerで検証したタイムライン
CSS @import
Chromeと違い@import部分でも読み込みに大きな差がでています。
何が原因なのかはこれだけではわかりませんね。
CSS link要素
Chromeとほぼ変わらず安定して読み込んでくれます。
Sass compile
Chromeと変わらず最速です。
CSSもモジュール化・コンポーネント化するメリットとまとめ
実はこの記事で言いたいことは@importの問題というよりはCSSをモジュール化・コンポーネント化するメリットにあります。
最近公開されたこちらの記事「画面ではなく部品から始めてみよう」でも言われているように固定の画面サイズに合わせたCSSをだらだらと記述するより、モジュール・コンポーネントを必要に応じて読み込む方が変化に強いのではないかと最近思い始めました。
Bootstrapは顕著な例でしょう。
モジュール化やコンポーネント化はiOSやAndroid、Adobe Flexや大規模なWebサイト開発ではすでに行われているかと思います。
個人的な主観ですが、小規模なWebサイトを作る際は、ページ単位でCSSを記述することが多く作っている時は良いけれども、運用中に変更する事があると手間が多く作りにくいなと感じていました。(変更は可能だが不要なCSSの消し忘れや消して他のページにも影響したなど手間がかかる)
Sassが使えなかった時はモジュール化するには@importを使うしか方法がなく管理のしやすさとサイトの表示速度のどちらかしか実現できません(正確にはサーバー側で処理させるなど方法はある)。
これからは、Sassなどのメタ言語を利用しコンパイルを行うことで今回のサンプルのように管理のしやすさを維持しつつ、サイトの高速化も実現することができます。
今後はWeb Componentsも利用できるようになるとHTMLのコンポーネント化が可能になりよりモジュール化やコンポーネント化を意識した構築方法にく変化していくと思います。
考え方を今から少しずつ変えていきたいですね。
@importの問題についてはより詳しい検証を行っているこちらの記事も参考になります。
@importを使うべきでない理由